package org.jeecg.modules.fk.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import org.jeecg.modules.fk.mapper.auto.model.RiskCwbgDbmxKey;
import org.jeecg.modules.fk.mapper.auto.model.RiskQysdsSbqk;
import org.jeecg.modules.fk.mapper.auto.model.RiskQysdsSbqkKey;
import org.jeecg.modules.fk.mapper.auto.model.RiskZzsSbqk;
import org.jeecg.modules.fk.mapper.manual.model.riskprocesslist.AllTypeRiskReportRespDTO;
import org.jeecg.modules.fk.mapper.manual.model.RiskCwbgDbmxExt;
import org.jeecg.modules.fk.constant.ZbTypeEnum;
import org.jeecg.modules.fk.vo.inner.resp.RiskFpxgmFpqkRespDTO;
import org.jeecg.modules.fk.vo.inner.resp.RiskZzsxgmSbqkRespDTO;
import org.jeecg.modules.fk.vo.req.*;
import org.jeecg.modules.fk.vo.resp.FxmxRespDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.*;

/**
 * @title: RiskDashboardService.java
 * @package: org.jeecg.modules.fk.mapper.service
 * @description: 风险面板服务
 * @author: yuancheng
 * @date: 2020-12-21 11:22
 */

@Slf4j
@Service
public class RiskDashboardService {

    @Autowired
    private RiskFpService riskFpService;

    //    @Lazy
    @Autowired
    private FxmxService fxmxService;

    //    @Lazy
    @Autowired
    private RiskCbService riskCbService;

    //    @Lazy
    @Autowired
    private RiskProcessService riskProcessService;

    public Map<String, Object> getRiskDashboardData(RiskDashboardReqDto dto) {
        Map<String, Object> resultMap = new HashMap<>();

        String nsrsbh = dto.getNsrsbh();
        String areaCode = dto.getAreaCode();
        String skssqq = dto.getSkssqq();
        String skssqz = dto.getSkssqz();
        String agentId = dto.getAgentId();
        String yearSkssqq = dto.getYearSkssqq();
        String yearSkssqz = dto.getYearSkssqz();
        String ybnsrbz = dto.getYbnsrbz();
        boolean isGeneralTaxpayer = true;

        if (true == ObjectUtils.isEmpty(ybnsrbz) || false == "Y".equalsIgnoreCase(ybnsrbz)) {
            isGeneralTaxpayer = false;
        }

        // 进项作废发票分页查询
        JxzffpDto jxzffpDto = new JxzffpDto();
//        BeanUtils.copyProperties(dto, jxzffpDto);
        jxzffpDto.setGmfNsrsbh(nsrsbh);
        jxzffpDto.setAreaCode(areaCode);
        jxzffpDto.setKprqq(skssqq);
        jxzffpDto.setKprqz(skssqz);
        jxzffpDto.setPageNo(1);
        jxzffpDto.setPageSize(1);
        String resultJxzffp = this.riskFpService.getJxzffp(jxzffpDto);
        if (false == ObjectUtils.isEmpty(resultJxzffp)) {
            cn.hutool.json.JSON parse = JSONUtil.parse(resultJxzffp);
            Object parseResult = JSON.parse(resultJxzffp);
            resultMap.put("Jxzffp", parseResult);
        }

        ZbTypeEnum zbType = ZbTypeEnum.ZZS;
        FxmxRespDTO resultFxmx = this.fxmxService.getFxmx(zbType, nsrsbh, skssqq, skssqz, agentId);
        if (false == ObjectUtils.isEmpty(resultFxmx)) {
            resultMap.put("Fxmx_" + zbType.toString(), resultFxmx);
        }

        resultFxmx = null;
        zbType = ZbTypeEnum.ZZSFP;
        resultFxmx = this.fxmxService.getFxmx(zbType, nsrsbh, skssqq, skssqz, agentId);
        if (false == ObjectUtils.isEmpty(resultFxmx)) {
            resultMap.put("Fxmx_" + zbType.toString(), resultFxmx);
        }

        RiskZzsSbqkReqDTO riskZzsSbqkReqDTO = new RiskZzsSbqkReqDTO();
        riskZzsSbqkReqDTO.setNsrsbh(nsrsbh);
        riskZzsSbqkReqDTO.setSkssqq(skssqq);
        riskZzsSbqkReqDTO.setSkssqz(skssqz);
        RiskZzsSbqk resultRiskZzsSbqk = this.fxmxService.getRiskZzsSbqk(riskZzsSbqkReqDTO);
        if (false == ObjectUtils.isEmpty(resultRiskZzsSbqk)) {
            resultMap.put("RiskZzsSbqk", resultRiskZzsSbqk);
        }

        resultFxmx = null;
        zbType = ZbTypeEnum.QYSDS;
        resultFxmx = this.fxmxService.getFxmx(zbType, nsrsbh, yearSkssqq, yearSkssqq, agentId);
        if (false == ObjectUtils.isEmpty(resultFxmx)) {
            resultMap.put("Fxmx_" + zbType.toString(), resultFxmx);
        }

//        zbType = ZbTypeEnum.CWBB;
        RiskCwbgDbmxKey riskCwbgDbmxKey = new RiskCwbgDbmxKey();
        riskCwbgDbmxKey.setNsrsbh(nsrsbh);
        Date dateYearSkssqq = DateUtil.parse(yearSkssqq);
        riskCwbgDbmxKey.setSkssqq(dateYearSkssqq);
        Date dateYearSkssqz = DateUtil.parse(yearSkssqz);
        riskCwbgDbmxKey.setSkssqz(dateYearSkssqz);
        RiskCwbgDbmxExt resultCwbgDbmxExt = this.riskCbService.getCwbgDbmxExt(riskCwbgDbmxKey);
        if (false == ObjectUtils.isEmpty(resultCwbgDbmxExt)) {
            resultMap.put("CwbgDbmxExt", resultCwbgDbmxExt);
        }

        RiskQysdsSbqkKey riskQysdsSbqkKey = new RiskQysdsSbqkKey();
        riskQysdsSbqkKey.setNsrsbh(nsrsbh);
        riskQysdsSbqkKey.setSkssqq(dateYearSkssqq);
        riskQysdsSbqkKey.setSkssqz(dateYearSkssqz);
        RiskQysdsSbqk riskQysdsSbqk = this.fxmxService.getRiskQysdsSbqk(riskQysdsSbqkKey);
        if (false == ObjectUtils.isEmpty(riskQysdsSbqk)) {
            resultMap.put("RiskQysdsSbqk", riskQysdsSbqk);
        }

        AllTypeRiskReportReqDTO allTypeRiskReportReqDTO = new AllTypeRiskReportReqDTO();
        allTypeRiskReportReqDTO.setNsrsbh(nsrsbh);
        allTypeRiskReportReqDTO.setSkssqq(skssqq);
        allTypeRiskReportReqDTO.setSkssqz(skssqz);
        allTypeRiskReportReqDTO.setYearSkssqq(yearSkssqq);
        allTypeRiskReportReqDTO.setYearSkssqz(yearSkssqz);
        AllTypeRiskReportRespDTO resultAllTypeLastReport = this.riskProcessService.getAllTypeLastReport(allTypeRiskReportReqDTO);
        if (false == ObjectUtils.isEmpty(resultAllTypeLastReport)) {
            resultMap.put("AllTypeLastReport", resultAllTypeLastReport);
        }

        if (false == isGeneralTaxpayer) {
            RiskZzsxgmSbqkReqDTO riskZzsxgmSbqkReqDTO = new RiskZzsxgmSbqkReqDTO();
            riskZzsxgmSbqkReqDTO.setNsrsbh(nsrsbh);
            riskZzsxgmSbqkReqDTO.setSkssqq(skssqq);
            riskZzsxgmSbqkReqDTO.setSkssqz(skssqz);
            riskZzsxgmSbqkReqDTO.setAgentId(agentId);
            RiskZzsxgmSbqkRespDTO riskZzsxgmSbqk = this.fxmxService.getRiskZzsxgmSbqk(riskZzsxgmSbqkReqDTO);
            if (false == ObjectUtils.isEmpty(riskZzsxgmSbqk)) {
                resultMap.put("RiskZzsxgmSbqk", riskZzsxgmSbqk);
            }

            RiskFpxgmFpqkReqDto riskFpxgmFpqkReqDto = new RiskFpxgmFpqkReqDto();
            riskFpxgmFpqkReqDto.setNsrsbh(nsrsbh);
            riskFpxgmFpqkReqDto.setSkssqq(skssqq);
            riskFpxgmFpqkReqDto.setSkssqz(skssqz);
            riskFpxgmFpqkReqDto.setAgentId(agentId);
            RiskFpxgmFpqkRespDTO riskFpxgmFpqk = this.fxmxService.getRiskFpxgmFpqk(riskFpxgmFpqkReqDto);
            if (false == ObjectUtils.isEmpty(riskFpxgmFpqk)) {
                resultMap.put("RiskFpxgmFpqk", riskFpxgmFpqk);
            }
        }

        return resultMap;
    }

    public Map<String, Object> getRiskDashboardDataMT(RiskDashboardReqDto dto) {
        Map<String, Object> resultMap = new ConcurrentHashMap<>();

        String nsrsbh = dto.getNsrsbh();
        String areaCode = dto.getAreaCode();
        String skssqq = dto.getSkssqq();
        String skssqz = dto.getSkssqz();
        String agentId = dto.getAgentId();
        String yearSkssqq = dto.getYearSkssqq();
        String yearSkssqz = dto.getYearSkssqz();
        String ybnsrbz = dto.getYbnsrbz();

        try {
            //creating the ThreadPoolExecutor
            ThreadPoolExecutor executor = new ThreadPoolExecutor(9, 9,
                    0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
//            ExecutorService executor = Executors.newFixedThreadPool(8);

            List<Callable<Void>> callables = Arrays.asList(() -> {
                        // 进项作废发票分页查询
                        JxzffpDto jxzffpDto = new JxzffpDto();
//        BeanUtils.copyProperties(dto, jxzffpDto);
                        jxzffpDto.setGmfNsrsbh(nsrsbh);
                        jxzffpDto.setAreaCode(areaCode);
                        jxzffpDto.setKprqq(skssqq);
                        jxzffpDto.setKprqz(skssqz);
                        jxzffpDto.setPageNo(1);
                        jxzffpDto.setPageSize(1);
                        String resultJxzffp = this.riskFpService.getJxzffp(jxzffpDto);
                        if (false == ObjectUtils.isEmpty(resultJxzffp)) {
                            cn.hutool.json.JSON parse = JSONUtil.parse(resultJxzffp);
                            Object parseResult = JSON.parse(resultJxzffp);
                            resultMap.put("Jxzffp", parseResult);
                        }

                        return null;
                    },
                    () -> {
                        ZbTypeEnum zbType = ZbTypeEnum.ZZS;
                        FxmxRespDTO resultFxmx = this.fxmxService.getFxmx(zbType, nsrsbh, skssqq, skssqz, agentId);
                        if (false == ObjectUtils.isEmpty(resultFxmx)) {
                            resultMap.put("Fxmx_" + zbType.toString(), resultFxmx);
                        }

                        return null;
                    },
                    () -> {
                        ZbTypeEnum zbType = ZbTypeEnum.ZZSFP;
                        FxmxRespDTO resultFxmx = this.fxmxService.getFxmx(zbType, nsrsbh, skssqq, skssqz, agentId);
                        if (false == ObjectUtils.isEmpty(resultFxmx)) {
                            resultMap.put("Fxmx_" + zbType.toString(), resultFxmx);
                        }

                        return null;
                    },
                    () -> {
                        RiskZzsSbqkReqDTO riskZzsSbqkReqDTO = new RiskZzsSbqkReqDTO();
                        riskZzsSbqkReqDTO.setNsrsbh(nsrsbh);
                        riskZzsSbqkReqDTO.setSkssqq(skssqq);
                        riskZzsSbqkReqDTO.setSkssqz(skssqz);
                        RiskZzsSbqk resultRiskZzsSbqk = this.fxmxService.getRiskZzsSbqk(riskZzsSbqkReqDTO);
                        if (false == ObjectUtils.isEmpty(resultRiskZzsSbqk)) {
                            resultMap.put("RiskZzsSbqk", resultRiskZzsSbqk);
                        }

                        return null;
                    },
                    () -> {
                        ZbTypeEnum zbType = ZbTypeEnum.QYSDS;
                        FxmxRespDTO resultFxmx = this.fxmxService.getFxmx(zbType, nsrsbh, yearSkssqq, yearSkssqq, agentId);
                        if (false == ObjectUtils.isEmpty(resultFxmx)) {
                            resultMap.put("Fxmx_" + zbType.toString(), resultFxmx);
                        }

                        return null;
                    },
                    () -> {
//                        ZbTypeEnum zbType = ZbTypeEnum.CWBB;
                        RiskCwbgDbmxKey riskCwbgDbmxKey = new RiskCwbgDbmxKey();
                        riskCwbgDbmxKey.setNsrsbh(nsrsbh);
                        Date dateYearSkssqq = DateUtil.parse(yearSkssqq);
                        riskCwbgDbmxKey.setSkssqq(dateYearSkssqq);
                        Date dateYearSkssqz = DateUtil.parse(yearSkssqz);
                        riskCwbgDbmxKey.setSkssqz(dateYearSkssqz);
                        RiskCwbgDbmxExt resultCwbgDbmxExt = this.riskCbService.getCwbgDbmxExt(riskCwbgDbmxKey);
                        if (false == ObjectUtils.isEmpty(resultCwbgDbmxExt)) {
                            resultMap.put("CwbgDbmxExt", resultCwbgDbmxExt);
                        }

                        return null;
                    },
                    () -> {
                        RiskQysdsSbqkKey riskQysdsSbqkKey = new RiskQysdsSbqkKey();
                        riskQysdsSbqkKey.setNsrsbh(nsrsbh);
                        Date dateYearSkssqq = DateUtil.parse(yearSkssqq);
                        riskQysdsSbqkKey.setSkssqq(dateYearSkssqq);
                        Date dateYearSkssqz = DateUtil.parse(yearSkssqz);
                        riskQysdsSbqkKey.setSkssqz(dateYearSkssqz);
                        RiskQysdsSbqk riskQysdsSbqk = this.fxmxService.getRiskQysdsSbqk(riskQysdsSbqkKey);
                        if (false == ObjectUtils.isEmpty(riskQysdsSbqk)) {
                            resultMap.put("RiskQysdsSbqk", riskQysdsSbqk);
                        }

                        return null;
                    },
                    () -> {
                        AllTypeRiskReportReqDTO allTypeRiskReportReqDTO = new AllTypeRiskReportReqDTO();
                        allTypeRiskReportReqDTO.setNsrsbh(nsrsbh);
                        allTypeRiskReportReqDTO.setSkssqq(skssqq);
                        allTypeRiskReportReqDTO.setSkssqz(skssqz);
                        allTypeRiskReportReqDTO.setYearSkssqq(yearSkssqq);
                        allTypeRiskReportReqDTO.setYearSkssqz(yearSkssqz);
                        AllTypeRiskReportRespDTO resultAllTypeLastReport = this.riskProcessService.getAllTypeLastReport(allTypeRiskReportReqDTO);
                        if (false == ObjectUtils.isEmpty(resultAllTypeLastReport)) {
                            resultMap.put("AllTypeLastReport", resultAllTypeLastReport);
                        }

                        return null;
                    },
                    () -> {
                        boolean isGeneralTaxpayer = true;
                        if (true == ObjectUtils.isEmpty(ybnsrbz) || false == "Y".equalsIgnoreCase(ybnsrbz)) {
                            isGeneralTaxpayer = false;
                        }

                        if (false == isGeneralTaxpayer) {
                            RiskZzsxgmSbqkReqDTO riskZzsxgmSbqkReqDTO = new RiskZzsxgmSbqkReqDTO();
                            riskZzsxgmSbqkReqDTO.setNsrsbh(nsrsbh);
                            riskZzsxgmSbqkReqDTO.setSkssqq(skssqq);
                            riskZzsxgmSbqkReqDTO.setSkssqz(skssqz);
                            riskZzsxgmSbqkReqDTO.setAgentId(agentId);
                            RiskZzsxgmSbqkRespDTO riskZzsxgmSbqk = this.fxmxService.getRiskZzsxgmSbqk(riskZzsxgmSbqkReqDTO);
                            if (false == ObjectUtils.isEmpty(riskZzsxgmSbqk)) {
                                resultMap.put("RiskZzsxgmSbqk", riskZzsxgmSbqk);
                            }
                        }

                        return null;
                    },
                    () -> {
                        boolean isGeneralTaxpayer = true;
                        if (true == ObjectUtils.isEmpty(ybnsrbz) || false == "Y".equalsIgnoreCase(ybnsrbz)) {
                            isGeneralTaxpayer = false;
                        }

                        if (false == isGeneralTaxpayer) {

                            RiskFpxgmFpqkReqDto riskFpxgmFpqkReqDto = new RiskFpxgmFpqkReqDto();
                            riskFpxgmFpqkReqDto.setNsrsbh(nsrsbh);
                            riskFpxgmFpqkReqDto.setSkssqq(skssqq);
                            riskFpxgmFpqkReqDto.setSkssqz(skssqz);
                            riskFpxgmFpqkReqDto.setAgentId(agentId);
                            RiskFpxgmFpqkRespDTO riskFpxgmFpqk = this.fxmxService.getRiskFpxgmFpqk(riskFpxgmFpqkReqDto);
                            if (false == ObjectUtils.isEmpty(riskFpxgmFpqk)) {
                                resultMap.put("RiskFpxgmFpqk", riskFpxgmFpqk);
                            }
                        }

                        return null;
                    }
            );

            executor.invokeAll(callables).forEach(f ->
            {
                try {
                    f.get();
                } catch (InterruptedException | ExecutionException e) {
                    log.error("RiskDashboardService.getRiskDashboardDataMT, Exception:{}", e);
                }
            });

            executor.shutdown();
        } catch (InterruptedException e) {
            log.error("RiskDashboardService.getRiskDashboardDataMT, Exception:{}", e);
        }

        return resultMap;
    }

}
